 
  

 






<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=237 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
<head>
 <title>
  Java Practices -> Plugin Factory
 </title>
 <link rel="stylesheet" type="text/css" href="../stylesheet8.css" media="all">
 
 <link rel="shortcut icon" href='../images/favicon.ico' type="image/vnd.microsoft.icon">
 <meta name="description" content="Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples.">
 
 <meta name='keywords' content='java,java programming,java practices,java idiom,java style,java design patterns,java coding conventions,'>
 
 
</head>
 
<body>


<div class='menu-bar'>
 
  <a href='../home/HomeAction.html' title='Table of Contents'>Home</a> |
  <a href='../vote/VoteSummaryAction-2.html' title='View Poll Results'>Poll</a> |
   
  <A href='../feedback/FeedbackAction451f-2.html?Operation=Show' title='Send Your Feedback'>Wiki</a> |
  <b><a href='../source/SourceAction-2.html' title='Grab Source Code'>Source Code</a></b><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |

  <a href='http://www.web4j.com/Java_Web_Application_Framework_Overview.jsp?From=1' title='Free Download - Java Web Application Framework'><b>WEB4J</b></a> |
  
  <a href='http://www.date4j.net/' title='Replacement for java.util.Date'><b>DATE4J</b></a> |

   <a href='../references/ReferencesAction-2.html' title='References'>Links</a>
   
  <form action='http://www.javapractices.com/search/SearchAction.do' method='get' class='search-form'>
   <input type='text' name='SearchTerms' value="" size=12 maxlength=50 class='search'>
   <input type='submit' value="Search">
  </form>
 
</div>

<P>



  

 






<p class="display-messages">

 

 

</p>


<div class="main-layout">
 
   

 




<div class='page-title'>Plugin Factory</div>

<div class='main-body'>
 
<br>
It's often useful to be able to quickly and easily switch one implementation of a given feature with another. 
This is especially useful when writing unit tests for your code, but the technique isn't 
strictly limited only to unit tests.

<P>A <em>plugin factory</em> is one way of quickly swapping implementations.
The general idea is to :
<ul>
 <li>define a Java interface for the methods whose implementation you want to be able to swap.
 <li>define 2 or more concrete implementations of that interface.
 <li>create a corresponding method in a plugin factory class to return one of those 
  implementations, as defined by some configuration setting. 
</ul>

<P>Using configuration of some kind (often simply a properties file), the plugin factory knows which 
concrete implementation it's supposed to return to its caller.

<P>It's important that your application treat the Plugin Factory as the <i>sole source</i> for implementations of the 
corresponding interfaces. That is, the rest of your app is not supposed to have <i>direct</i> knowledge of 
the concrete implementations. The Plugin Factory is meant to keep that knowledge secret.

<P>A plugin factory can have a number of methods defined, each returning an implementation of a 
specific interface.

<P>A recurring theme in object programming is <b>allowing old code to call new code</b>. 
A Plugin Factory is simply another variation on that important theme.

<P><b>Example</b>

<P>As an example, let's take the idea of a <a href='TopicActionec62-2.html?Id=234'>fake system clock</a>.
In this case, you want the current time to be defined centrally, in one place. You also want to 
be able to swap in various ways of defining the current time, either for testing or for other reasons.

<P>Here's the interface :
<br>
<PRE>

<span class='keyword'>package</span> myapp;

<span class='comment'>/**
 Return the time in milliseconds from the Java epoch.
 When combined with a TimeZone, such a millisecond value can be 
 used to create a date-time value.
 
 Variation: one might decide to return a date-time object directly, 
 instead of a millisecond value.
*/</span>
<span class='keyword'>public</span> <span class='keyword'>interface</span> TimeSource {
  
  <span class='keyword'>long</span> currentTimeMillis();
  
}
 
</PRE>
<br>
<P>Here's an example of a particular concrete implementation of the above interface :
<br>
<PRE>

<span class='keyword'>package</span> hirondelle.jp.util;

<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> TimeSourceOneDayAdvance <span class='keyword'>implements</span> TimeSource {
  
  <span class='keyword'>public</span> <span class='keyword'>long</span> currentTimeMillis() {
    <span class='keyword'>return</span> System.currentTimeMillis() + MILLISECS_PER_DAY;
  }
  
  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> <span class='keyword'>int</span> MILLISECS_PER_DAY = <span class='literal'>1000</span>*<span class='literal'>60</span>*<span class='literal'>60</span>*<span class='literal'>24</span>;
}
 
</PRE>
<br>
Here's a caller that uses a concrete implementation, without knowing its underlying class :
<br>
<PRE>

<span class='keyword'>package</span> myapp;

<span class='comment'>/**
Use a concrete implementation of an interface, without being linked directly to the 
the implementing class.

The concrete implementation is known only to the PluginFactory class.
*/</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> UseFakeSystemClock {
  
  <span class='keyword'>public</span> <span class='keyword'>void</span> doSomethingThatDependsOnTime(){
    TimeSource timesource = PluginFactory.getTimeSource();
    <span class='keyword'>long</span> currentTime = timesource.currentTimeMillis();
    System.out.println(<span class='literal'>"Current millisecond value: "</span> + currentTime);
  }

}
 
</PRE>
<br>
Finally, here's a sketch of the Plugin Factory itself. Note that you can add more methods to this class, each 
corresponding to a different interface.
<br>
<PRE>

<span class='keyword'>package</span> myapp;

<span class='keyword'>import</span> java.util.LinkedHashMap;
<span class='keyword'>import</span> java.util.Map;

<span class='comment'>/** Return concrete implementations for specific, known interfaces. */</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> PluginFactory {
  
  <span class='comment'>/**
   Read in configuration data that maps names of interfaces to names of 
   corresponding concrete implementation classes. Called early upon startup, 
   before any implementations are needed by the rest of the program.
   
   &lt;P&gt;Example of a possible entry in such a config file :
   myapp.TimeSource = myapp.TimeSourceOneDayAdvance
  */</span>
  <span class='keyword'>public</span> <span class='keyword'>static</span> <span class='keyword'>void</span> init(){
    <span class='comment'>//elided
</span>    <span class='comment'>//perhaps a properties file is read, perhaps some other source is used
</span>  }
  
  <span class='comment'>/*
  * Another variation: allow the caller to swap in different implementation classes
  * at runtime, after calling init. This allows testing code to swap in various 
  * implementations.
  */</span>
  
  <span class='comment'>/**
   Return the concrete implementation of the TimeSource interface.
  */</span>
  <span class='keyword'>public</span> <span class='keyword'>static</span> TimeSource getTimeSource() {
    String implClassName = fImplementations.get(<span class='literal'>"myapp.TimeSource"</span>);
    TimeSource result = (TimeSource)buildObject(implClassName);
    <span class='keyword'>return</span> result;
  }
  
  <span class='comment'>// PRIVATE
</span>  
  <span class='comment'>/**
   Map the name of an interface to the name of a corresponding concrete 
   implementation class. 
  */</span>
  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> Map&lt;String, String&gt; fImplementations = 
    <span class='keyword'>new</span> LinkedHashMap&lt;String, String&gt;()
  ;
  
  <span class='keyword'>private</span> <span class='keyword'>static</span> Object buildObject(String aClassName){
    Object result = <span class='keyword'>null</span>;
    <span class='keyword'>try</span> {
      <span class='comment'>//note that, with this style, the implementation needs to have a
</span>      <span class='comment'>//no-argument constructor!
</span>      Class implClass = Class.forName(aClassName);
      result = implClass.newInstance();
    }
    <span class='keyword'>catch</span> (ClassNotFoundException ex) {
      <span class='comment'>//elided
</span>    }
    <span class='keyword'>catch</span> (InstantiationException ex) {
      <span class='comment'>//elided
</span>    }
    <span class='keyword'>catch</span> (IllegalAccessException ex) {
      <span class='comment'>//elided
</span>    }
    <span class='keyword'>return</span> result;
  }
}
 
</PRE>
<br>
<br>
<br>

</div>




<div class='topic-section'>See Also :</div>
<div class='main-body'>
 
  
  <a href='TopicActionddc6-2.html?Id=113'>Construct Object using class name</a> <br>
 
  
  <a href='TopicActionec62-2.html?Id=234'>Use a fake system clock</a> <br>
 
</div>


<div class='topic-section'>Would you use this technique?</div>
<div class='main-body'>
  
  <form action="http://www.javapractices.com/vote/AddVoteAction.do" method='post'>
    Yes<input type='radio' name='Choice' value='Y' >
    &nbsp;&nbsp;No<input type='radio' name='Choice' value='N'>
    &nbsp;&nbsp;Undecided<input type='radio' name='Choice' value="?" >
    &nbsp;&nbsp;<input type=submit value="Vote" >
    <input type='hidden' name='Operation' value='Apply'>
    <input type='hidden' name='TopicId' value='237'>
  </form>
</div>

<div style='height:10.0em;'></div>

 
 
</div>

  

 





<div align='center' class='legalese'>  
&copy; 2011 Hirondelle Systems |
<a href='../source/SourceAction-2.html'><b>Source Code</b></a><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |
<a href="mailto:webmaster@javapractices.com">Contact</a> |
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/">License</a> |
<a href='../apps/cjp.rss'>RSS</a>
<!-- ukey="2AC36CD2" -->
<!-- ckey="16DF3D87" -->
<br>

 Individual code snippets can be used under this <a href='../LICENSE.txt'>BSD license</a> - Last updated on June 6, 2010.<br>
 Over 150,000 unique IPs last month - <span title='Java Practices 2.6.5, Mon May 16 00:00:00 EDT 2011'>Built with</span> <a href='http://www.web4j.com/'>WEB4J</a>.<br>
 - In Memoriam : Bill Dirani -
</div>

<script src="../../www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2633428-1";
urchinTracker();
</script>



</body>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=237 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:07 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
</html>
